package com.xbongbong.saas.util;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.enums.SheetTypeEnum;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.FundTransferEnum;
import com.xbongbong.saas.enums.business.OtherExpenseEnum;
import com.xbongbong.saas.enums.business.OtherIncomeEnum;
import com.xbongbong.saas.enums.business.PaySheetEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * @author 吴峰
 * @date 2021/08/04 15:24
 */
public class FundUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(FundUtil.class);

    /**
     * 得到资金账户字段的saasAttr集合
     * @return java.util.List<java.lang.String>
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public static List<String> getFundAccountSaasAttrList(){
        //资金账户对应saasAttr
        return Arrays.asList(PaymentSheetEnum.FUND_ACCOUNT.getSaasAttr(), PaySheetEnum.FUND_ACCOUNT.getSaasAttr(), OtherIncomeEnum.FUND_ACCOUNT.getSaasAttr(), OtherExpenseEnum.FUND_ACCOUNT.getSaasAttr(), FundTransferEnum.OUT_FUND_ACCOUNT.getSaasAttr(), FundTransferEnum.IN_FUND_ACCOUNT.getSaasAttr());
    }
    /**
     * 得到付款单的付款金額（核销金额）
     * @param data 付款单data
     * @param paySheetType 付款单类型
     * @return double
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public static double getSheetAmount4PaySheet(JSONObject data, String paySheetType) throws XbbException {
        if (data == null) {
            return 0;
        }
        PaySheetEnum amountEnum;
        if (Objects.equals(SheetTypeEnum.WRITE_OFF_PREPAY.getCode(), paySheetType)) {
            //預付款核銷則讀取核銷金額
            amountEnum = PaySheetEnum.WRITE_OFF_AMOUNT;
        } else {
            //其他類型付款單則讀付款金額
            amountEnum = PaySheetEnum.AMOUNT;
        }
        double amount = validateNum(amountEnum.getAttr(), amountEnum.getAttrName(), data);
        return amount;
    }

    /**
     * 校验数字类型字段
     * 参照FormDataValidateDataHelp内数字字段校验方法validateNum
     * @param key 字段attr
     * @param attrName 字段名
     * @param data 数据
     * @return java.lang.Double
     * @throws XbbException
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public static Double validateNum(String key, String attrName, JSONObject data) throws XbbException {
        try {
            String numStr = data.getString(key);
            Double num = null;
            if(Objects.nonNull(numStr) && !"null".equals(numStr)) {
                //防止数字已经格式化为#,###.##格式
                numStr = numStr.replaceAll(",", "");
                //兼容多单位单价导入
                numStr = numStr.replaceAll("\\|", "");
                numStr = numStr.replaceAll("｜", "");
                try {
                    BigDecimal bigDecimal = new BigDecimal(numStr);
                    num = bigDecimal.doubleValue();
                } catch (NumberFormatException e) {
                    LOGGER.error("validateNum error:" + numStr + ",key:" + key + ",attrName:" + attrName);
                    LOGGER.error("validateNum error",e);
                    num = null;
                }
            }
            // 校验数据是否是数字
            if(num == null){
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100018, String.format(MessageConstant.DATA_NOT_STANDARD, attrName));
            }
            return num;
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOGGER.error("DataValidateHelp.validateNum校验数据的正常格式", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    /**
     * 获取回/付款单的金额：（已经确定是哪种类型回/付款单）
     * 【注：如果能确定是哪种业务，则不建议使用该方法，可以 直接分别调用getSheetAmount4PaymentSheet、getSheetAmount4PaySheet】
     * @param sheetTypeEnum 已经确定是哪种类型回/付款单
     * @param data 回/付款的实体data
     * @return double 回/付款金额 or 核销金额
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public static double getSheetAmountBySheetType(SheetTypeEnum sheetTypeEnum, JSONObject data) throws XbbException {
        if (data == null) {
            return 0;
        }
        //是否为付款单类型
        if (Objects.equals(sheetTypeEnum.getXbbRefTypeEnum(), XbbRefTypeEnum.PAY_SHEET)) {
            //付款金额or核销金额
            return getSheetAmount4PaySheet(data, sheetTypeEnum.getCode());
        } else if (Objects.equals(sheetTypeEnum.getXbbRefTypeEnum(), XbbRefTypeEnum.OTHER_INCOME)) {
            return data.getDoubleValue(OtherIncomeEnum.AMOUNT.getAttr());
        } else if (Objects.equals(sheetTypeEnum.getXbbRefTypeEnum(), XbbRefTypeEnum.OTHER_EXPENSE)) {
            return data.getDoubleValue(OtherExpenseEnum.AMOUNT.getAttr());
        } else {
            //回款金额or核销金额
            return getSheetAmount4PaymentSheet(data, sheetTypeEnum.getCode());
        }
    }

    /**
     * 得到回款单的回款金額（核销金额）
     * @param data 回款单data
     * @param paymentSheetType 回款单类型
     * @return double
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public static double getSheetAmount4PaymentSheet(JSONObject data, String paymentSheetType) {
        if (data == null) {
            return 0;
        }
        double amount;
        if (SheetTypeEnum.onlyWriteOffAmount(paymentSheetType)) {
            //預收款核銷則、红冲预收款核销(退到余额)讀取核銷金額
            amount = data.getDoubleValue(PaymentSheetEnum.WRITE_OFF_AMOUNT.getAttr());
        } else {
            //其他類型回款單則讀回款金額
            amount = data.getDoubleValue(PaymentSheetEnum.AMOUNT.getAttr());
        }
        return amount;
    }
}
